﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bluyel.Core
{
    /// <summary>
    /// A data LOV.
    /// has a typeLOV
    /// </summary>
    public abstract class DEnumBase : DataNamedBase, IDEnum
    {
        /// <summary>
        /// Selection mode of the type.
        /// If type is Single or Many: all data have the same mode than the type.
        /// 
        /// If type mode is SetInVar, each data mode can be choosen between Single or Many.
        /// </summary>
        TypeEnumSelectMode _typeSelectMode = TypeEnumSelectMode.Single;

        /// <summary>
        /// Selection mode: single value or many values.
        /// </summary>
        DEnumSelectMode _selectMode = DEnumSelectMode.Single;

        /// <summary>
        /// List of Selected value(s): one or more, depending on the type.
        /// </summary>
        private List<IValue> _listSelectedValues = new List<IValue>();

        //=====================================================================
        #region Constructor.

        //---------------------------------------------------------------------
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name"></param>
        public DEnumBase(string name, ITypeEnum type)
            : base(name, type)
        {
            if (type != null)
                _typeSelectMode = type.SelectMode;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name"></param>
        public DEnumBase(string name, ITypeEnum type, DEnumSelectMode selectMode)
            : base(name, type)
        {
            if (type == null)
                return;

            _typeSelectMode= type.SelectMode;

            if (type.SelectMode == TypeEnumSelectMode.SetInVar)
            {
                _selectMode = selectMode;
                return;
            }

            ConvertTypeSelectModeToDataSelectMode();
        }
        #endregion

        //=====================================================================
        #region Properties.

        //---------------------------------------------------------------------
        // TypeLOV
        public ITypeEnum TypeEnum
        { get { return Type as ITypeEnum; } }

        //---------------------------------------------------------------------
        public TypeEnumSelectMode TypeSelectMode
        {
            get { return _typeSelectMode;  }
        }

        //---------------------------------------------------------------------
        public DEnumSelectMode SelectMode
        {
            get { return _selectMode; }
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return the selected value, can be null.
        /// If selection mode is many, return the first one.
        /// </summary>
        public IValue SelectedVal
        {
            get
            {
                if (_listSelectedValues.Count > 0)
                    return _listSelectedValues[0];
                return null;
            }
        }

        /// <summary>
        /// Return the list of selected values, use it if selection mode is many.
        /// </summary>
        public IEnumerable<IValue> ListSelectedVal 
        {
            get { return _listSelectedValues; } 
        }

        #endregion

        //=====================================================================
        #region Public methods.

        //---------------------------------------------------------------------
        public int ClearSelection()
        {
            int count = _listSelectedValues.Count;
            _listSelectedValues.Clear();

            return count;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Define the mode: Single value selected, or possibles to many values selected.
        /// </summary>
        /// <param name="mode"></param>
        //public void SetMode(TypeLOVSelectMode mode)
        //{
        //    _mode = mode;

        //    // refresh the list of selectd values
        //    // TODO:
        //}


        //---------------------------------------------------------------------
        /// <summary>
        /// Select this value.
        /// Must be present in the values typeLOV.
        /// </summary>
        /// <param name="dvValue"></param>
        /// <returns></returns>
        public bool SelectVal(IValue dvValue)
        {
            if (dvValue == null)
                return false;
            // must exists in the values of the typeLOV
            if (!(Type as ITypeEnum).Contains(dvValue))
                return false;

            if(_typeSelectMode == TypeEnumSelectMode.Single)
                ClearSelection();

            _listSelectedValues.Add(dvValue);
            return true;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Select a value in the LOV, by position.
        /// Set -1 to to have no selection. 
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public IValue SelectValAt(int pos)
        {
            if (pos < 0 || pos >= (Type as ITypeEnum).ValuesCount)
                return null;

            // clear the previous selection if select mode is single
            if(_selectMode == DEnumSelectMode.Single)
                ClearSelection();

            // get the value from the type
            IValue dv= (Type as ITypeEnum).GetAt(pos);
            if (dv == null)
                return null;

            _listSelectedValues.Add(dv);
            return dv;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// exp: 
        /// a=LOV:12
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string s = Name + "=";
            //if (_dataValue == null)
            //    s += Type.ToString() + "(null)";
            //else
            //    s += _dataValue.ToString();
            return s;
        }
        #endregion

        //=====================================================================
        #region Private Methods.

        //---------------------------------------------------------------------
        private void ConvertTypeSelectModeToDataSelectMode()
        {
            if (_typeSelectMode == TypeEnumSelectMode.Single)
                _selectMode = DEnumSelectMode.Single;

            if (_typeSelectMode == TypeEnumSelectMode.Many)
                _selectMode = DEnumSelectMode.Many;
        }

        #endregion
    }
}
